#include "../../include/main/dll.hpp"

std::mutex screen_mutex;

void windowInit(drawer::Screen& screen,object::ColorWorld& world){
    // 初始化第一步，初始化窗口
    auto result= drawer::initDrawer(windowWidth,windowHeight);
    if (result.status!=Result<GLFWwindow *, std::string>::Status::Ok){
        std::cout<<result.error<<std::endl;
        return;
    }
    auto window=result.value;


    // 开始进入线程，对屏幕内容进行修改
    std::thread handle(handler::MainHandler<object::ColorWorld>, std::ref(screen), std::ref(screen_mutex),std::ref(world));

    // 开始进行循环绘制屏幕内容
    drawer::loopDraw(window,screen,screen_mutex);

    
    drawer::destroyDrawer(window);
    handle.detach();
    // 结束前，清理资源
}

// Define the opaque structs
struct Screen_t {
    drawer::Screen screen;
    Screen_t(int width, int height) : screen(width, height) {}
};

struct Camera_t {
    camera::Camera camera;
    Camera_t() : camera(camera::generateCamera1()) {}
};

struct ColorWorld_t {
    object::ColorWorld world;
    ColorWorld_t(const camera::Camera& cam) : world(cam) {}
};

struct ColorCube_t {
    object::ColorCube cube;
    ColorCube_t(int x, int y, int z, int size) : cube(Dot(x, y, z), size) {}
};

struct ColorRound_t {
    object::ColorRound round;
    ColorRound_t(int x, int y, int z, float radius) : round(Dot(x, y, z), radius) {}
};

// Implement the C wrapper functions
extern "C" {

ScreenHandle createScreen(int width, int height) {
    return new Screen_t(width, height);
}

void destroyScreen(ScreenHandle screen) {
    delete screen;
}

CameraHandle createCamera() {
    return new Camera_t();
}

void destroyCamera(CameraHandle camera) {
    delete camera;
}

ColorWorldHandle createWorld(CameraHandle camera) {
    return new ColorWorld_t(camera->camera);
}

void destroyWorld(ColorWorldHandle world) {
    delete world;
}

ColorCubeHandle createCube(int x, int y, int z, int size) {
    return new ColorCube_t(x, y, z, size);
}

void destroyCube(ColorCubeHandle cube) {
    delete cube;
}

ColorRoundHandle createRound(int x, int y, int z, float radius) {
    return new ColorRound_t(x, y, z, radius);
}

void destroyRound(ColorRoundHandle round) {
    delete round;
}

void addCubeToWorld(ColorWorldHandle world, ColorCubeHandle cube) {
    world->world.insertColorObject(cube->cube);
}

void addRoundToWorld(ColorWorldHandle world, ColorRoundHandle round) {
    world->world.insertColorObject(round->round);
}

void startRendering(ScreenHandle screen, ColorWorldHandle world) {
    windowInit(screen->screen, world->world);
}

} // extern "C"